package org.oep;


import java.util.Enumeration;
import java.util.Hashtable;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class JMingle extends MIDlet implements CommandListener {
	// Our handlers
	private BTHandler bt;
	private MingleTracker mingleHandler;
	
	// The screens
	private Mingler mingleScreen;
	private Alert confirmationScreen;
	
	// Misc. crap
	private Command quit, scan, persistentScan, clearMessageLog, cancelScan, clearMingles, confirmOK, confirmCANCEL, optionsOK, optionsCANCEL;
	private Display display;
	
	private Form optionsScreen;
	private Hashtable options;
	private ValueScroller persistentScanInterval;
	
	public static final int BT_SEARCH_DONE = 0;
	public static final int EVENT_OCCURED = 1;

	
	public JMingle() {
		display = Display.getDisplay(this);

		optionsScreen = new Form("Options");
		persistentScanInterval = new ValueScroller("Scan interval", "m", 1, 60, 5);
		optionsScreen.append(persistentScanInterval);
		options = new Hashtable();
		
		confirmationScreen = new Alert("Confirm action",
				"Delete your mingles? This can't be undone.",
				null,
				AlertType.CONFIRMATION);
		
		quit = new Command("Quit", Command.EXIT, 1);
		scan = new Command("Scan", Command.OK, 1);
		persistentScan = new Command("Persistent scan", Command.OK, 3);
		clearMessageLog = new Command("Clear log", Command.ITEM, 4);
		clearMingles = new Command("Clear mingles", Command.ITEM, 5);
		cancelScan = new Command("Cancel scan", Command.CANCEL, 1);
		confirmOK = new Command("OK", Command.OK, 1);
		confirmCANCEL = new Command("Cancel", Command.CANCEL, 1);
		optionsOK = new Command("OK", Command.OK, 1);
		optionsCANCEL = new Command("Cancel", Command.CANCEL, 1);

		confirmationScreen.addCommand(confirmOK);
		confirmationScreen.addCommand(confirmCANCEL);
		optionsScreen.addCommand(optionsOK);
		optionsScreen.addCommand(optionsCANCEL);
		
		confirmationScreen.setCommandListener(this);		
	}
	
	/*
	 * Inherited from MIDlet
	 */
	//--------------------------------------------------------------//

	protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
		if(mingleHandler.countSavedDevices() != mingleHandler.numberOfDevices()) {
			mingleScreen.showMessage("Normalizing mingles...");
			mingleHandler.exportToRecordStore();
		}
				
	}

	protected void pauseApp() {

	}

	protected void startApp() throws MIDletStateChangeException {
		// Please note that the order in which we initialize some things is very
		// important. Things that are constructed using 'this' are in here, and
		// some are interdependent on one another.
		
		// Initialize some of the major components
		setOpt("persistent_scan_interval", "1");
		mingleHandler = new MingleTracker(this);
		bt = new BTHandler(this, mingleHandler);
		
		// The meat of the UI
		mingleScreen = new Mingler(this);
		mingleScreen.setCommandListener(this);
		
		// Try to show a fluffy loading screen
		LoadScreen loadScreen = new LoadScreen(mingleHandler);
		
		display.setCurrent(loadScreen);
		
		// Give some time to paint
		try {
			Thread.sleep(1000);
		}
		catch (Exception e) { }
		
		// Start the load
		mingleHandler.doLoad();
		display.setCurrent(mingleScreen);
		loadScreen.die();
		loadScreen = null;

		// If bluetooth isn't on, lock down
		if(bt.isInitialized()) {
			this.addDefaultCommands();
			mingleScreen.showMessage("Loaded " + mingleHandler.numberOfDevices() + " mingles");
		} else {
			mingleScreen.addCommand(quit);
			mingleScreen.showMessage("Bluetooth not initalized.");
		}
	}

	/*
	 * Inherited from CommandListener
	 */
	//--------------------------------------------------------------//
	
	public void commandAction(Command cmd, Displayable screen) {
		if(cmd == quit) {
			try {
	            destroyApp(false);
	            notifyDestroyed();
			} catch(Exception e) {}
		} else if(cmd == scan) {
			bt.killPersistentScan();
			bt.doNewSearch();
			removeAllCommands();
			mingleScreen.addCommand(cancelScan);
			mingleScreen.addCommand(clearMessageLog);
		} else if(cmd == persistentScan) {
			bt.stopScan();
			bt.startPersistentScan();
			removeAllCommands();
			mingleScreen.addCommand(cancelScan);
			mingleScreen.addCommand(clearMessageLog);
		} else if(cmd == clearMessageLog) {
			mingleScreen.clearMessageLog();
		} else if(cmd == cancelScan) {
			bt.stopScan();
			bt.killPersistentScan();
			removeAllCommands();
			this.addDefaultCommands();
		} else if(cmd == clearMingles) {
			display.setCurrent(confirmationScreen);
		} else if(cmd == confirmOK || cmd == confirmCANCEL) {
			if(cmd == confirmOK) {
				mingleHandler.eraseAll();
			}
			display.setCurrent(mingleScreen);
		} else if(cmd == optionsOK || cmd == optionsCANCEL) {
			if(cmd == optionsOK) {
				String val = String.valueOf( persistentScanInterval.getValue() );
				options.put("persistent_scan_interval", val);
			}
			persistentScanInterval.setValue( persistentScanInterval.getDefault() );
			
		}
	}	
	
	/*
	 * For external use
	 */
	//--------------------------------------------------------------//
	// For processing signals from the other classes
	public void tell(String msg) {
		mingleScreen.showMessage(msg);
	}
	
	public void processCode(int code) {
		switch(code) {
		case BT_SEARCH_DONE: this.removeAllCommands(); this.addDefaultCommands(); break;
		case EVENT_OCCURED: mingleScreen.repaint(); break;
		}
	}
	
	public boolean antennaIsBusy() {
		return bt.antennaIsBusy();
	}
	
	public boolean persistentScanActive() {
		return bt.persistentScanActive();
	}
	
	public int numberOfDevices() {
		return mingleHandler.numberOfDevices();
	}
	
	public Enumeration getDevices() {
		return mingleHandler.getDevices();
	}
	
	public void setOpt(String name, String val) {
		options.put(name.toLowerCase(), val);
	}
	
	public String getOpt(String name) {
		return (String) options.get(name.toLowerCase());
	}
	

	/*
	 * For internal use
	 */
	//--------------------------------------------------------------//
	
	private void removeAllCommands() {
		mingleScreen.removeCommand(quit);
		mingleScreen.removeCommand(scan);
		mingleScreen.removeCommand(persistentScan);
		mingleScreen.removeCommand(clearMessageLog);
		mingleScreen.removeCommand(cancelScan);
		mingleScreen.removeCommand(clearMingles);
	}
	
	private void addDefaultCommands() {
		mingleScreen.addCommand(quit);
		mingleScreen.addCommand(scan);
		mingleScreen.addCommand(persistentScan);
		mingleScreen.addCommand(clearMessageLog);
		mingleScreen.addCommand(clearMingles);
	}
}
